home *** CD-ROM | disk | FTP | other *** search
- ; Realtime Bitmap Rotation Routine
- ; Handles approx. 0.5 million pixels / second on a 386
- ; by Soeren Holstebroe (seap)
- ; no group but available if you are interested. (code / algorithms + music)
- ;
- ; Last edited: 10/10-1993
- ;
- ; I would really appreciate if you would send some of your own source-codes
- ; or/and anything you use this piece of code in or/and any improvement of
- ; this routine.
- ; Note: This is freeware. You may do with this code whatever you want, but
- ; hey! please leave a greeting in your program. You greet me, I greet you.
- ; If any problems turn up or if you want to exchange more sources or if you
- ; just want to say "Hi! nice/lame piece of code you have made" or if you
- ; actually used this piece of asm, please write.
- ;
- ; Write to:
- ; Internet: seap@diku.dk
- ; Fidonet : 2:230/159.16
- ; Snailnet: Hjortekærbakken 1
- ; 2800 Lyngby
- ; Denmark
- ; NB! Don't write to the snailnet address too long after release-date.
-
- .286
- cseg segment
- assume cs:cseg;ds:dseg
- org 0100h ; stak
- start: jmp main
-
- oldmode DB ?
-
- opengfx:
- mov ah,0fh
- int 10h
- mov oldmode,al
- mov ah,0h
- mov al,13h
- int 10h
- ret
-
- closegfx:
- mov ah,0h
- mov al,oldmode
- int 10h
- ret
-
- makemulstab: xor di,di
- xor ax,ax
- mov cx,(iwidth*iheight)
- mulsloop: mov mulstab [di],ax
- add ax,iwidth
- inc di
- inc di
- loop mulsloop
- ret
-
-
- retrace: mov dx,3dah ; wait for vertical retrace
- ventl: in al,dx
- and al,8
- jz ventl
- venth: in al,dx
- and al,8
- jne venth
- ret
-
-
-
- tempX dw 0
- tempY dw 0
- cosvx dw 0
- sinvx dw 0
- cosvy dw 0
- sinvy dw 0
- cosv dw 0
- sinv dw 0
-
-
- rotate proc near
- mov bp,angle ; bp = rotation-angle
- mov ax,cos[bp] ; get cos(bp) and sin(bp) (for speed)
- mov cosv,ax
- mov ax,sin[bp]
- mov sinv,ax
-
- mov cx,iheight ; image-iheight
- mov bx,(-(iheight/2)); bx = -iheight/2
- mov di,0
-
- ; pre-calc all multiplications
-
- mov ax,-(iwidth/2)
- imul cosv
- mov cosvx,ax ; cosvx = cos v * X
-
- mov ax,-(iwidth/2)
- imul sinv
- mov sinvx,ax ; sinvx = sin v * X
-
- mov ax,-(iheight/2)
- imul cosv
- mov cosvy,ax ; cosvy = cos v * Y
-
- mov ax,-(iheight/2)
- imul sinv
- mov sinvy,ax ; sinvy = sin v * Y
-
- @ry: push cx
- mov cx,iwidth ; image iwidth
-
- ; dx = sin v * Y + cos v * X
- mov dx,sinvy
- add dx,cosvx
-
- ; dx = cos v * Y - sin v * X
- mov si,cosvy
- sub si,sinvx
-
- ; Place rotation origin in center of sourceimage
- add dx,(iwidth/2)*256
- add si,(iheight/2)*256
-
- @rx:
- ; Xo = sin v * Y + cos v * X
- ; Yo = cos v * Y - sin v * X
-
-
- cmp dx,(iwidth)*256 ; check if x is within source
- jae blackout
-
- cmp si,(iwidth)*256 ; the same for y
- jae blackout
-
-
- ; Get-pixel
- ; calculate source-image offset
- getpixel:
- mov bx,si ; y = y/128 (fixed point)
- xchg bh,bl
- xor bh,bh
- add bx,bx
- mov ax,mulstab[bx] ; get y offset
- xor bx,bx ; x = x/256 (fixed point)
- mov bl,dh
- add bx,ax ; si = source = iwidth * Yo + Xo
- mov al,ds:image2[bx] ; al = pixel color
- ; change the above line if
- ; you want another image.
- ; Remember to change iwidth and
- ; iheight as well
- jmp plot_pixel
- blackout:
- mov al,0 ; black pixel
-
- plot_pixel:
- mov es:[di],al ; display pixel
- inc di ; next dest. pixel
- ; NOTE!!!!
- ; This will run faster
- ; if two colors are computed
- ; before the video-card is
- ; being accesed.
- ; When two colors are computed
- ; you can use a word-write
- ; instead of the byte-write.
- ; If you own a 386 DX, you can
- ; even wait until you have
- ; computed 4 colors before you
- ; acces the video-ram.
- ; I have made byte-writes
- ; to make it more compatible, but...
- ; Well, please mail me any
- ; improvements.
- ; update tempX
- add dx,cosv
- ; bx = sin v * Y + cos v * X
- ; update tempY
- sub si,sinv
- ; si = cos v * Y - sin v * X
-
- loop @jrx
-
- ; update screen coord
- add di,(320-iwidth) ; next dest. line
-
- ; update sinvy & cosvy
- mov ax,cosv
- add cosvy,ax
- mov ax,sinv
- add sinvy,ax
-
- pop cx
- loop @jry
- ret
-
- ; the far jumps below can easily be removed to gain speed.
- ; They are only there for compatibility (gosh, that word was hard to spell).
-
- @jrx: jmp @rx
- @jry: jmp @ry
-
- rotate endp
-
-
- main:
-
- mov ah,0ch ; kill keyboard buffer
- mov al,-1
- int 21h
-
- call opengfx ; open mode 13
- ; precalculate image-y-offsets
- call makemulstab
- push cs
- pop ds
- mov ax,0a000h
- mov es,ax
-
- mloop:
- call rotate
- add angle,2
- and angle,1feh
- ; Angle goes from 0 to 255 degree. Remember to double
- ; the offset. (for wordsize).
-
- call retrace ; wait for v-blank
- mov ah,1 ; check if kb-buffer is empty
- int 16h
- jz mloop ; nope, loop again
-
- call closegfx
-
- mov ah,4ch ; return to dos
- int 21h
-
- mulstab DW (iwidth*iheight) DUP(?)
-
- angle dw 0 ; rotation angle
- iwidth = 100 ; image width
- iheight = 100 ; image height
- ; the two constants above
- ; can easily be changed
- ; into declarations.
- ; test-pattern nr. 1
-
- image1 db 0,0,0,0,12,14,15,16,17,18,0,0,0,0,0,0
- db 0,0,0,11,13,19,0,0,0,20,21,22,0,0,0,0
- db 0,0,9,10,0,0,0,0,0,0,23,24,0,0,0,0
- db 0,0,8,0,0,0,0,0,0,0,0,25,0,0,0,0
- db 0,0,7,6,0,0,0,0,0,0,0,26,27,0,0,0
- db 0,0,0,5,4,0,0,0,0,0,0,28,29,0,0,0
- db 0,0,0,0,3,2,1,0,0,0,0,30,31,0,0,0
- db 0,0,0,0,0,0,0,0,0,0,32,33,0,0,0,0
- db 0,0,0,0,0,0,0,0,0,34,35,36,0,0,0,0
- db 0,0,0,0,0,0,0,0,37,38,39,0,0,0,0,0
- db 0,0,0,0,0,0,0,40,41,42,43,0,0,0,0,0
- db 0,0,0,0,0,0,44,45,46,47,0,0,0,0,0,0
- db 0,0,0,0,48,49,50,51,52,0,0,0,0,0,0,0
- db 0,0,0,53,54,55,56,57,0,0,0,0,0,0,0,0
- db 0,0,58,59,60,61,62,63,0,0,0,0,0,0,0,0
- db 0,64,65,66,67,68,69,70,71,0,0,0,0,0,0,0
-
- ; test-pattern nr. 2 (compiles a bit slow)
-
- image2 label byte
- rept (100*25)
- db 0,0,0,40
- endm
-
- ; precalculated sin/cos table
- ; table-size: 256+64=320
-
-
- sin DW 00000h,00006h,0000ch,00012h,00018h,0001fh,00025h,0002bh
- DW 00031h,00037h,0003dh,00044h,0004ah,0004fh,00055h,0005bh
- DW 00061h,00067h,0006dh,00072h,00078h,0007dh,00083h,00088h
- DW 0008dh,00092h,00097h,0009ch,000a1h,000a6h,000abh,000afh
- DW 000b4h,000b8h,000bch,000c1h,000c5h,000c9h,000cch,000d0h
- DW 000d4h,000d7h,000dah,000ddh,000e0h,000e3h,000e6h,000e9h
- DW 000ebh,000edh,000f0h,000f2h,000f4h,000f5h,000f7h,000f8h
- DW 000fah,000fbh,000fch,000fdh,000fdh,000feh,000feh,000feh
- cos DW 000ffh,000feh,000feh,000feh,000fdh,000fdh,000fch,000fbh
- DW 000fah,000f8h,000f7h,000f5h,000f4h,000f2h,000f0h,000edh
- DW 000ebh,000e9h,000e6h,000e3h,000e0h,000ddh,000dah,000d7h
- DW 000d4h,000d0h,000cch,000c9h,000c5h,000c1h,000bch,000b8h
- DW 000b4h,000afh,000abh,000a6h,000a1h,0009ch,00097h,00092h
- DW 0008dh,00088h,00083h,0007dh,00078h,00072h,0006dh,00067h
- DW 00061h,0005bh,00055h,0004fh,0004ah,00044h,0003dh,00037h
- DW 00031h,0002bh,00025h,0001fh,00018h,00012h,0000ch,00006h
- DW 00000h,0fffah,0fff4h,0ffeeh,0ffe8h,0ffe1h,0ffdbh,0ffd5h
- DW 0ffcfh,0ffc9h,0ffc3h,0ffbch,0ffb6h,0ffb1h,0ffabh,0ffa5h
- DW 0ff9fh,0ff99h,0ff93h,0ff8eh,0ff88h,0ff83h,0ff7dh,0ff78h
- DW 0ff73h,0ff6eh,0ff69h,0ff64h,0ff5fh,0ff5ah,0ff55h,0ff51h
- DW 0ff4ch,0ff48h,0ff44h,0ff3fh,0ff3bh,0ff37h,0ff34h,0ff30h
- DW 0ff2ch,0ff29h,0ff26h,0ff23h,0ff20h,0ff1dh,0ff1ah,0ff17h
- DW 0ff15h,0ff13h,0ff10h,0ff0eh,0ff0ch,0ff0bh,0ff09h,0ff08h
- DW 0ff06h,0ff05h,0ff04h,0ff03h,0ff03h,0ff02h,0ff02h,0ff02h
- DW 0ff02h,0ff02h,0ff02h,0ff02h,0ff03h,0ff03h,0ff04h,0ff05h
- DW 0ff06h,0ff08h,0ff09h,0ff0bh,0ff0ch,0ff0eh,0ff10h,0ff13h
- DW 0ff15h,0ff17h,0ff1ah,0ff1dh,0ff20h,0ff23h,0ff26h,0ff29h
- DW 0ff2ch,0ff30h,0ff34h,0ff37h,0ff3bh,0ff3fh,0ff44h,0ff48h
- DW 0ff4ch,0ff51h,0ff55h,0ff5ah,0ff5fh,0ff64h,0ff69h,0ff6eh
- DW 0ff73h,0ff78h,0ff7dh,0ff83h,0ff88h,0ff8eh,0ff93h,0ff99h
- DW 0ff9fh,0ffa5h,0ffabh,0ffb1h,0ffb6h,0ffbch,0ffc3h,0ffc9h
- DW 0ffcfh,0ffd5h,0ffdbh,0ffe1h,0ffe8h,0ffeeh,0fff4h,0fffah
- DW 00000h,00006h,0000ch,00012h,00018h,0001fh,00025h,0002bh
- DW 00031h,00037h,0003dh,00044h,0004ah,0004fh,00055h,0005bh
- DW 00061h,00067h,0006dh,00072h,00078h,0007dh,00083h,00088h
- DW 0008dh,00092h,00097h,0009ch,000a1h,000a6h,000abh,000afh
- DW 000b4h,000b8h,000bch,000c1h,000c5h,000c9h,000cch,000d0h
- DW 000d4h,000d7h,000dah,000ddh,000e0h,000e3h,000e6h,000e9h
- DW 000ebh,000edh,000f0h,000f2h,000f4h,000f5h,000f7h,000f8h
- DW 000fah,000fbh,000fch,000fdh,000fdh,000feh,000feh,000feh
-
- cseg ends
- END start
-
- ; seap was here :)
-